const request = require("request");
const os = require("os");
const ifaces = os.networkInterfaces();
const crypto = require("crypto");
const qs = require("qs");
const DONGLE_HOST = "---DONGLE_HOST---";
const DG = "---DG---";

const EncryptUtil = {
  algorithm: { ecb: "des-ecb", cbc: "des-cbc" },
  encrypt: (plaintext, Key) => {
    const key = new Buffer(Key);
    const iv = new Buffer(Key);
    const cipher = crypto.createCipheriv(EncryptUtil.algorithm.cbc, key, iv);
    cipher.setAutoPadding(true); //default true
    let ciph = cipher.update(plaintext, "utf8", "base64");
    ciph += cipher.final("base64");
    return ciph;
  },
  decrypt: (encrypt_text, Key) => {
    const key = new Buffer(Key);
    const iv = new Buffer(Key);
    const decipher = crypto.createDecipheriv(
      EncryptUtil.algorithm.cbc,
      key,
      iv
    );
    decipher.setAutoPadding(true);
    let txt = decipher.update(encrypt_text, "base64", "utf8");
    txt += decipher.final("utf8");
    return txt;
  },
};

const NetworkUtil = {
  getMac: () => {
    let mac = "";
    Object.keys(ifaces).forEach((ifname) => {
      ifaces[ifname].forEach((iface) => {
        if ("IPv4" !== iface.family || iface.internal !== false) {
          return;
        }
        mac = iface.mac;
      });
    });
    return mac;
  },

  getIP: () => {
    let ip = "";
    Object.keys(ifaces).forEach((ifname) => {
      ifaces[ifname].forEach((iface) => {
        if ("IPv4" !== iface.family || iface.internal !== false) {
          return;
        }
        ip = iface.address;
      });
    });
    return ip;
  },
};

const getPM = (res) => {
  const RM = JSON.parse(res).Tag.Version;
  console.log(RM, res, "RM===");
  if (RM) {
    const arr = RM.split(",");
    const obj = {};
    arr.forEach((a) => {
      const v = a.split(":");
      obj[v[0]] = typeof v[1] === "string" ? v[1] * 1 : v[1];
    });
    if (obj.type * 1 === 1) {
      return obj;
    } else {
      return null;
    }
  }
};

const getDongleInfo = () => {
  const url = DONGLE_HOST + "/api/EmulatorBS/GetDongleInfo";
  console.log(NetworkUtil.getMac(), NetworkUtil.getIP(), "getIP");
  const requestData = {
    AppId: "8358d2a41dee55e5be903ff99f7c923b",
    Version: "1.0.0",
    Mac: NetworkUtil.getMac(),
    IP: NetworkUtil.getIP(),
  };
  const query = qs.stringify(requestData);
  return new Promise((resolve, reject) => {
    request(
      {
        url:
          url +
          "?q=" +
          encodeURIComponent(EncryptUtil.encrypt(query, "20190906")),
        method: "POST",
        json: true,
        headers: {
          "content-type": "application/json",
          encrypt: true,
          timestamp: EncryptUtil.encrypt(
            String(new Date().getTime()),
            "20190906"
          ),
        },
        body: requestData,
      },
      (error, response, body) => {
        if (!error && response.statusCode === 200) {
          //   resolve(JSON.parse(EncryptUtil.decrypt(body, "20190906")));
          const res = getPM(JSON.parse(EncryptUtil.decrypt(body, "20190906")));
          console.log(res, "====end res===");
          resolve(res);
        } else {
          reject();
        }
      }
    );
  });
};

const doAuthorize = () => {
  const url = DONGLE_HOST + "/api/User/Authorize";
  const requestData = {
    AppId: "8358d2a41dee55e5be903ff99f7c923b",
    Version: "1.0.0",
    Mac: NetworkUtil.getMac(),
    IP: NetworkUtil.getIP(),
  };
  const query = qs.stringify(requestData);
  return new Promise((resolve, reject) => {
    request(
      {
        url:
          url +
          "?q=" +
          encodeURIComponent(EncryptUtil.encrypt(query, "20190906")),
        method: "POST",
        json: true,
        headers: {
          "content-type": "application/json",
          encrypt: true,
          timestamp: EncryptUtil.encrypt(
            String(new Date().getTime()),
            "20190906"
          ),
        },
        body: requestData,
      },
      (error, response, body) => {
        if (!error && response.statusCode === 200) {
          let res = JSON.parse(
            JSON.parse(EncryptUtil.decrypt(body, "20190906"))
          );
          if (res.ResultCode * 1 === 1) {
            resolve(res);
          } else if (res.ResultCode * 1 === 0) {
            setTimeout(() => {
              doAuthorize();
            }, 3000);
          }
        } else {
          reject();
        }
      }
    );
  });
};

module.exports = async (ctx, next) => {
  //   const res = await getDongleInfo();
  let res = null;
  if (DG * 1 === 1) {
    res = {
      account: 6,
      course: 4,
      resource: 4,
      task: 6,
      online: 3,
      type: 1,
    };
  }
  ctx.dongleInfo = res;
  await next();
};
